import time
import logging
from dataclasses import dataclass
from common.request_util_test import RequestUtil
from config import datas


@dataclass
class InstallationParams:
    url: str
    method: str
    headers: dict = None
    data: dict = None


class ExtensionComponent:

    @classmethod
    def is_installed(cls, name):
        """检查扩展组件是否已安装"""
        uri = "/clusters/host/rest/application-management/v1beta1/helm-releases?extension=true"
        url = datas.baseUrl + uri
        response = RequestUtil().send_request("GET", url, headers={"Content-Type": "application/json"})

        if response.status_code != 200:
            logging.error(f"检查已安装扩展组件失败，状态码: {response.status_code}")
            return False

        for item in response.json()["data"]["items"]:
            if name in item["name"]:
                logging.info("检测到当前已安装扩展组件")
                return True
        return False

    @classmethod
    def installing(cls, params: InstallationParams, url_verify, timeout: float = 120):
        """安装扩展组件"""
        response = RequestUtil().send_request(method=params.method, url=params.url, headers=params.headers,
                                              json=params.data)
        if response.status_code != 202:
            logging.error(f"安装请求失败，状态码: {response.status_code}")
            return False

        return ExtensionComponent._wait_for_installation(url_verify, timeout)

    @classmethod
    def _wait_for_installation(cls, verify_url: str, timeout: float = 120) -> bool:
        """等待安装完成"""
        logging.info("开始检测扩展组件是否安装成功")
        start_time = time.time()
        poll_interval = 2

        while time.time() - start_time < timeout:
            response = RequestUtil().send_request("GET", verify_url)
            status_code = response.status_code

            if status_code == 200:
                elapsed = time.time() - start_time
                logging.info(f"扩展组件安装成功，共耗时: {elapsed}秒")
                return True

            if str(abs(status_code))[0] != "5" and status_code != 400:
                logging.error(f"出现预期之外的状态码: {status_code}，请手工排查")
                return False

            elapsed = time.time() - start_time
            logging.info(f"组件安装中...已等待{elapsed}秒")
            time.sleep(poll_interval)

        logging.error("ERR: 扩展组件在指定时间内仍未安装完毕")
        return False

    @classmethod
    def uninstall(cls, params: InstallationParams, url_verify, timeout: float = 120):
        """卸载扩展组件"""
        response = RequestUtil().send_request(method=params.method, url=params.url)
        if response.status_code != 200:
            logging.error(f"卸载失败，状态码: {response.status_code}")
            return False

        return ExtensionComponent._wait_for_uninstall(url_verify, timeout=timeout)

    @classmethod
    def _wait_for_uninstall(cls, verify_url: str, timeout: float = 120) -> bool:
        """等待卸载完成"""
        logging.info("开始检测扩展组件是否卸载成功")
        start_time = time.time()
        poll_interval = 2

        while time.time() - start_time < timeout:
            response = RequestUtil().send_request("GET", verify_url)
            status_code = response.status_code

            if status_code == 404:
                elapsed = time.time() - start_time
                logging.info(f"扩展组件卸载成功，共耗时: {elapsed}秒")
                return True

            elapsed = time.time() - start_time
            logging.info(f"组件卸载中...已等待{elapsed}秒")
            time.sleep(poll_interval)

        logging.error("ERR: 扩展组件在指定时间内仍未卸载完成，请手动检查")
        return False
